package io.mft.runtime.thread;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import io.mft.api.domain.Regulation;
import io.mft.commons.exception.MFTException;
import io.mft.commons.multithreading.worker.ThreadPoolManager;
import io.mft.dev.base.ApiThreadExecutorConfig;
import io.mft.runtime.MFTApiExecutor;
import io.mft.runtime.config.ConfigLoaderProvider;
import lombok.extern.slf4j.Slf4j;

/**
 * 规则异步执行线程池
 * 
 * @说明：TODO
 * @类型名称：AsyncExecuteThreadPool
 * @创建者: 胡常建
 * @创建时间: 2021年7月5日 下午4:56:44
 * @修改者: 胡常建
 * @修改时间: 2021年7月5日 下午4:56:44
 */
@Slf4j
public class AsyncExecuteThreadPool {
	static Map<String, ApiThreadExecutorConfig> map=new HashMap<String, ApiThreadExecutorConfig>();
	/**
	 * 初始化规则线程池
	 * @说明: TODO
	 * @方法名称: initAsyncThreadPool
	 * @参数 @param api
	 * @参数 @param apiRegulation
	 * @返回类型 void    
	 * @创建者: 胡常建  
	 * @创建时间: 2021年7月5日 下午4:58:13
	 * @修改者: 胡常建  
	 * @修改时间: 2021年7月5日 下午4:58:13
	 */
	public static void initAsyncThreadPool() {
		ConfigLoaderProvider configLoaderProvider=MFTApiExecutor.getInstance().getConfigLoaderProvider();
		List<ApiThreadExecutorConfig> configs=configLoaderProvider.apiThreadExecutorConfigLoader().load(MFTApiExecutor.getInstance().getAppId());
		configs.forEach(config->{
			map.put(config.threadExecutorId(), config);
			create(config);
		});
	}
	private static void create(ApiThreadExecutorConfig config) {
		ThreadPoolTaskExecutor threadPoolExecutor=ThreadPoolManager.create(config.threadExecutorId(), config.getMaxPoolSize(), config.getMaxPoolSize(), config.getWorkQueueCapacity());
		log.warn("初始化异步执行线程池,最小线程:{},最大线程数:{},队列容量:{},线程池ID[{}]",threadPoolExecutor.getCorePoolSize(),threadPoolExecutor.getMaxPoolSize(),threadPoolExecutor.getThreadPoolExecutor().getQueue().remainingCapacity(),config.threadExecutorId());
	}
	public static void registerThreadExecutor(ApiThreadExecutorConfig config) {
		if (map.containsKey(config.threadExecutorId())) {
			ApiThreadExecutorConfig t=map.get(config.threadExecutorId());
			if (t.getMaxPoolSize()!=config.getMaxPoolSize()||t.getWorkQueueCapacity()!=config.getWorkQueueCapacity()) {
				ThreadPoolManager.shutdown(config.threadExecutorId());
				create(config);
			}
		}else {
			create(config);
		}
	}
	public interface AsyncWorker{
		void work();
	}
	public static Future<?> execute(Regulation regulation,AsyncWorker asyncWorker) {
		ThreadPoolTaskExecutor threadPoolTaskExecutor=ThreadPoolManager.get(regulation.getThreadExecutorId());
		if (threadPoolTaskExecutor==null) {
			throw new MFTException("未初始化线程池容器["+regulation.getThreadExecutorId()+"],请检查");
		}
		Runnable workRunnable=new Runnable() {
			public void run() {
				try {
					asyncWorker.work();
				} catch (Exception e) {
					log.error("",e);
				}
			}
		};
		return threadPoolTaskExecutor.submit(workRunnable);
	}
	
}
